﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections.ObjectModel;
using System.Diagnostics.Contracts;

namespace BE.Web.Betfair.Interface.Entities
{
    /// <summary>
    /// The BetRunner Price
    /// </summary>
    public sealed class BetRunnerPrice
    {
        [ContractInvariantMethod]
        void ObjectInvariant()
        {
            
            Contract.Invariant(this.BestBackPrices != null);
            Contract.Invariant(this.BestLayPrices != null);

        }

        /// <summary>
        /// Gets the actual BSP.
        /// </summary>
        /// <remarks>The actual Betfair Starting Price. Before the starting price is determined, this field contains zero.</remarks>
        /// <value>The actual BSP.</value>
        public double ActualBSP { get; private set; }

        /// <summary>
        /// Gets the Far BSP
        /// </summary>
        /// <remarks>What the starting price would be if the market was reconciled now taking into account only the currently place SP bets. The Far Price is not as complicated but not as accurate and only accounts for money on the exchange at SP.</remarks>
        public double FarBSP { get; private set; }

        /// <summary>
        /// Gets the near BSP
        /// </summary>
        /// <remarks>What the starting price would be if the market was reconciled now taking into account the SP bets as well as unmatched exchange bets on the same selection in the exchange.</remarks>
        public double NearBSP { get; private set; }

        /// <summary>
        /// 
        /// </summary>
        /// <remarks>Reduction in the odds that applies in case this runner does not participate</remarks>
        public double ReductionFactor { get; private set; }

        /// <summary>
        /// The Last matched Price
        /// </summary>
        public double LastPriceMatched { get; private set; }

        /// <summary>
        /// Total matched Amount
        /// </summary>
        /// <remarks>The total amount matched on this selection (regardless of price)</remarks>
        public double TotalAmountMatched { get; private set; }

        /// <summary>
        /// Gets or sets the asian line id.
        /// </summary>
        /// <value>The asian line id.</value>
        /// <remarks>Id of the selection (this will be the same for the same selection across markets)</remarks>
        public int AsianLineId { get; private set; }


        /// <summary>
        /// Gets or sets the selection id.
        /// </summary>
        /// <value>The selection id.</value>
        /// <remarks>Id of the selection (this will be the same for the same selection across markets)</remarks>
        public int SelectionId { get; private set; }


        /// <summary>
        /// Gets or sets the order id.
        /// </summary>
        /// <value>The order id.</value>
        /// <remarks>The order in which the items are displayed on Betfair</remarks>
        public int SortOrder { get; private 
            set; }
        /// <summary>
        /// Gets the bestprices for back
        /// </summary>
        /// <value>The best aviable back prices.</value>
        public ReadOnlyCollection<BetPrice> BestBackPrices { get; private set; }

        /// <summary>
        /// Gets the best prices for lay
        /// </summary>
        /// <value>The best aviable lay prices.</value>
        public ReadOnlyCollection<BetPrice> BestLayPrices { get; private set; }

        /// <summary>
        /// 
        /// </summary>
        /// <remarks>Used to indicate a Vacant Trap for withdrawn runners in Greyhound markets</remarks>
        public bool Vacant { get; private set; }

        /// <summary>
        /// Initializes a new instance of the <see cref="BetRunnerPrice"/> class.
        /// </summary>
        /// <param name="actualBsp">The actual BSP.</param>
        /// <param name="asianLineId">The asian line id.</param>
        /// <param name="bestBack">The best back.</param>
        /// <param name="bestLay">The best lay.</param>
        /// <param name="farBSP">far BSP</param>
        /// <param name="lastPriceMatched">the last price that was matched</param>
        /// <param name="nearBsp">The near BSP</param>
        /// <param name="reduction">Recudtions</param>
        /// <param name="totalAmount">the total amount</param>
        public BetRunnerPrice(double totalAmount,double actualBsp,double nearBsp,double farBSP,int asianLineId,IEnumerable<BetPrice> bestBack,IEnumerable<BetPrice> bestLay,
            double lastPriceMatched,double reduction)
        {
            #region conditions
            Contract.Ensures(this.BestBackPrices != null);
            Contract.Ensures(this.BestLayPrices != null);
            #endregion
            this.LastPriceMatched = lastPriceMatched;
            
            this.ActualBSP = actualBsp;
            this.NearBSP = nearBsp;
            this.FarBSP = farBSP;
            this.ReductionFactor = reduction;
            this.TotalAmountMatched = totalAmount;
            this.AsianLineId = asianLineId;
            
            List<BetPrice> back = new List<BetPrice>();
            List<BetPrice> lay = new List<BetPrice>();

            if (bestBack != null)
            {
                back.AddRange(bestBack);
            }

            if (bestLay != null)
            {
                lay.AddRange(bestLay);
            }

            this.BestLayPrices = new ReadOnlyCollection<BetPrice>(lay);
            this.BestBackPrices= new ReadOnlyCollection<BetPrice>(back);
        }

    }
}
